#include <stdio.h>  
#include <stdlib.h>  
#include <math.h>  
#include <string.h>  
#include <time.h>  

#define MAX_POINTS 200  

typedef struct {  
<<<<<<< HEAD
     double x;  
     double y;  
} Point;  

// 生成数据集部分  
void gendat(int t,   double a,     double b,   double c,     double d, const char* filename)   
=======
     long double x;  
     long double y;  
} Point;  

// 生成数据集部分  
void gendat(int t,   long double a,     long double b,   long double c,     long double d, const char* filename)   
>>>>>>> 1a1c99e (第一次修改)
{  
    FILE *file = fopen(filename, "w");  
    // if (!file) {  
    //     perror("Error opening file");  
    //     return;  
    // }  
    srand(time(NULL)); // 初始化随机数种子  

    for (int i = 0; i < MAX_POINTS; i++) {  
<<<<<<< HEAD
         double x =      (double)rand() / RAND_MAX * 200 - 100; // 生成-100到100之间的随机数  
         double y = 0;  
=======
         long double x =      (long double)rand() / RAND_MAX * 200 - 100; // 生成-100到100之间的随机数  
         long double y = 0;  
>>>>>>> 1a1c99e (第一次修改)

        switch (t) {  
            case 1: // 一次函数  
                y = a * x + b;  
                break;  
            case 2: // 二次函数  
                y = a * x * x + b * x + c;  
                break;  
            case 3: // 三次函数  
                y = a * x * x * x + b * x * x + c * x + d;  
                break;  
        }  

        // 添加噪声  
        y += (rand() / (RAND_MAX / 10.0)) - 5;  

<<<<<<< HEAD
        fprintf(file, "%lf %lf\n", x, y); // 写入文件  
=======
        fprintf(file, "%Lf %Lf\n", x, y); // 写入文件  
>>>>>>> 1a1c99e (第一次修改)
    }  

    fclose(file);  
}  

// 最小二乘法拟合  
void least_squares(const char* filename) {  
    Point points[MAX_POINTS];  
    int count = 0;  

    // 加载数据  
    FILE *file = fopen(filename, "r");  


<<<<<<< HEAD
    while (fscanf(file, "%lf %lf", &points[count].x, &points[count].y) == 2) {  
=======
    while (fscanf(file, "%Lf %Lf", &points[count].x, &points[count].y) == 2) {  
>>>>>>> 1a1c99e (第一次修改)
        count++;  
        if (count >= MAX_POINTS) break;  
    }  
    fclose(file);  

    // 计算参数  
<<<<<<< HEAD
     double sum_x = 0, sum_y = 0, sum_x2 = 0, sum_xy = 0;  
=======
     long double sum_x = 0, sum_y = 0, sum_x2 = 0, sum_xy = 0;  
>>>>>>> 1a1c99e (第一次修改)
    
    for (int i = 0; i < count; i++) {  
        sum_x += points[i].x;  
        sum_y += points[i].y;  
        sum_x2 += points[i].x * points[i].x;  
        sum_xy += points[i].x * points[i].y;  
    }  

<<<<<<< HEAD
     double a = (count * sum_xy - sum_x * sum_y) / (count * sum_x2 - sum_x * sum_x);  
     double b = (sum_y - a * sum_x) / count;  

    printf("Fit: y = %lfx + %lf\n", a, b);  
=======
     long double a = (count * sum_xy - sum_x * sum_y) / (count * sum_x2 - sum_x * sum_x);  
     long double b = (sum_y - a * sum_x) / count;  

    _mingw_printf("Fit: y = %Lfx + %Lf\n", a, b);  
>>>>>>> 1a1c99e (第一次修改)
}  

// 梯度下降法拟合  
void gradient_descent(const char* filename) {  
    Point points[MAX_POINTS];  
    int count = 0;  

    // 加载数据  
    FILE *file = fopen(filename, "r");  


<<<<<<< HEAD
    while (fscanf(file, "%lf %lf", &points[count].x, &points[count].y) == 2) {  
=======
    while (fscanf(file, "%Lf %Lf", &points[count].x, &points[count].y) == 2) {  
>>>>>>> 1a1c99e (第一次修改)
        count++;  
        if (count >= MAX_POINTS) break;  //防止溢出
    }  
    fclose(file);  

    // 初始化参数  
<<<<<<< HEAD
     double a = 0, b = 0; // 初始参数  
     double learning_rate = 0.001; // 学习率  
=======
     long double a = 0, b = 0; // 初始参数  
     long double learning_rate = 0.001; // 学习率  
>>>>>>> 1a1c99e (第一次修改)
    int iterations = 1000; // 迭代次数  

    // 梯度下降迭代计算参数  
    for (int iter = 0; iter < iterations; iter++) {  
<<<<<<< HEAD
         double gradient_a = 0;  
         double gradient_b = 0;  

        for (int i = 0; i < count; i++) {  
             double error = (a * points[i].x + b) - points[i].y;  
=======
         long double gradient_a = 0;  
         long double gradient_b = 0;  

        for (int i = 0; i < count; i++) {  
             long double error = (a * points[i].x + b) - points[i].y;  
>>>>>>> 1a1c99e (第一次修改)
            gradient_a += (2.0 / count) * error * points[i].x;  
            gradient_b += (2.0 / count) * error;  
        }  

        a -= learning_rate * gradient_a; // 更新a  
        b -= learning_rate * gradient_b; // 更新b  
    }  

<<<<<<< HEAD
    printf("Fit: y = %lfx + %lf\n", a, b);  
=======
    _mingw_printf("Fit: y = %Lfx + %Lf\n", a, b);  
>>>>>>> 1a1c99e (第一次修改)
}  
// 二次函数梯度下降法拟合  
void gradient_descent2(const char* filename) {  
    Point points[MAX_POINTS];  
    int count = 0;  

    // 加载数据  
    FILE *file = fopen(filename, "r");  


<<<<<<< HEAD
    while (fscanf(file, "%lf %lf", &points[count].x, &points[count].y) == 2) {  
=======
    while (fscanf(file, "%Lf %Lf", &points[count].x, &points[count].y) == 2) {  
>>>>>>> 1a1c99e (第一次修改)
        count++;  
        if (count >= MAX_POINTS) break;  
    }  
    fclose(file);  

    // 初始化参数  
<<<<<<< HEAD
     double a = 0, b = 0, c = 0; // 初始参数  
     double learning_rate = 0.001; // 学习率  
=======
     long double a = 0, b = 0, c = 0; // 初始参数  
     long double learning_rate = 0.001; // 学习率  
>>>>>>> 1a1c99e (第一次修改)
    int iterations = 1000; // 迭代次数  

    // 梯度下降迭代计算参数  
    for (int iter = 0; iter < iterations; iter++) {  
<<<<<<< HEAD
         double gradient_a = 0;  
         double gradient_b = 0;  
         double gradient_c = 0;  

        for (int i = 0; i < count; i++) {  
             double error = (a * points[i].x * points[i].x + b * points[i].x + c) - points[i].y;  
=======
         long double gradient_a = 0;  
         long double gradient_b = 0;  
         long double gradient_c = 0;  

        for (int i = 0; i < count; i++) {  
             long double error = (a * points[i].x * points[i].x + b * points[i].x + c) - points[i].y;  
>>>>>>> 1a1c99e (第一次修改)
            gradient_a += (2.0 / count) * error * points[i].x * points[i].x; // 对a的梯度  
            gradient_b += (2.0 / count) * error * points[i].x; // 对b的梯度  
            gradient_c += (2.0 / count) * error; // 对c的梯度  
        }  

        a -= learning_rate * gradient_a; // 更新a  
        b -= learning_rate * gradient_b; // 更新b  
        c -= learning_rate * gradient_c; // 更新c  
    }  

<<<<<<< HEAD
    printf("Fit: y = %lfx^2 + %lfx + %lf\n", a, b, c);  
}

int main() {  
    int t;  
     double a, b, c, d;  
=======
    _mingw_printf("Fit: y = %Lfx^2 + %Lfx + %Lf\n", a, b, c);  
}
// 三次函数梯度下降法拟合  
void gradient_descent3(const char* filename) {  
    Point points[MAX_POINTS];  
    int count = 0;  

    // 加载数据  
    FILE *file = fopen(filename, "r");  


    while (fscanf(file, "%Lf %Lf", &points[count].x, &points[count].y) == 2) {  
        count++;  
        if (count >= MAX_POINTS) break;  
    }  
    fclose(file);  

    // 初始化参数  
     double a = 0, b = 0, c = 0, d = 0; // 参数 a, b, c, d  
     double learning_rate = 0.001; // 学习率  
    int iterations = 10000; // 迭代次数  

    // 梯度下降迭代计算参数  
    for (int iter = 0; iter < iterations; iter++) {  
         double gradient_a = 0;  
         double gradient_b = 0;  
         double gradient_c = 0;  
         double gradient_d = 0;  

        for (int i = 0; i < count; i++) {  
             double x = points[i].x;  
             double y = points[i].y;  
             double prediction = (a * x * x * x) + (b * x * x) + (c * x) + d;  
             double error = prediction - y;  

            gradient_a += (3.0 / count) * error * x * x; // 对a的梯度  
            gradient_b += (2.0 / count) * error * x; // 对b的梯度  
            gradient_c += (1.0 / count) * error; // 对c的梯度  
            gradient_d += (1.0 / count) * error; // 对d的梯度  
        }  

        a -= learning_rate * gradient_a; // 更新a  
        b -= learning_rate * gradient_b; // 更新b  
        c -= learning_rate * gradient_c; // 更新c  
        d -= learning_rate * gradient_d; // 更新d  
    }  

    _mingw_printf("Fit: y = %Lfx^3 + %Lfx^2 + %Lfx + %Lf\n", a, b, c, d);  
}  
int main() {  
    int t;  
     long double a, b, c, d;  
>>>>>>> 1a1c99e (第一次修改)
    char method[10];  
    
    printf("function type : (1, 2, 3): ");  
    scanf("%d", &t);  
    printf("parameters : a, b, c, d: ");  
<<<<<<< HEAD
    scanf("%lf %lf %lf %lf", &a, &b, &c, &d);  
=======
    scanf("%Lf %Lf %Lf %Lf", &a, &b, &c, &d);  
>>>>>>> 1a1c99e (第一次修改)
    printf("method : (ls or gd): ");  
    scanf("%s", method);  

    // 生成数据集  
    gendat(t, a, b, c, d, "some.dat");  

    //选择拟合方式  
    if (strcmp(method, "ls") == 0) {  
        if (t == 1) least_squares("some.dat");
    } 
    else if (strcmp(method, "gd") == 0) {  
        if (t == 1) gradient_descent("some.dat"); 
        else if (t == 2)  gradient_descent2("some.dat"); 
<<<<<<< HEAD

=======
        else gradient_descent3("some.dat"); 
>>>>>>> 1a1c99e (第一次修改)
    } 

    return 0;  
}